package com.ecarx.vhaltests.hy11.testcases;

import android.car.VehicleAreaDoor;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import com.ecarx.vhaltests.CallbackTimer;
import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DoorMoveTest extends VhalUnitTestBase {
    private static final int REQ_CLOSE = 0;
    private static final int REQ_OPEN = 1;
    private static final int REQ_STOP = 2;

    private static final int STS_FULL_CLOSE = 1;
    private static final int STS_MOVE_UP = 2;
    private static final int STS_MOVE_UP_BREAK = 3;
    private static final int STS_STOP_DURING_OPEN = 4;
    private static final int STS_FULL_OPEN = 5;
    private static final int STS_MOVE_DOWN = 6;
    private static final int STS_MOVE_DOWN_BREAK = 7;
    private static final int STS_STOP_DURING_CLOSE = 8;
    private static final int STS_HALF_CLOSE = 9;
    private static final int STS_STOP_MIN_POSITION = 10;

    private CallbackTimer cbkTimer = new CallbackTimer();
    private CarPropertyManager.CarPropertyEventCallback propertyCbk;
    private static IpcpClient ipcpClient;
    private boolean isFirstCbk;

    @BeforeClass
    public static void testInit() {
        setAvailable(true);
        delay();
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        Assert.assertTrue(isAvail);
    }

    @Test
    public void test001_SetDoorMoveOpen() {
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, REQ_OPEN);
        delay();
        int value = mCarPropertyMgr.getIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        boolean ret = value == STS_MOVE_UP || value == STS_MOVE_UP_BREAK || value == STS_FULL_OPEN || value == STS_MOVE_DOWN || value == STS_MOVE_DOWN_BREAK;
        Assert.assertTrue(ret);
    }

    @Test
    public void test002_SetDoorMoveClose() {
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, REQ_CLOSE);
        delay();
        int value = mCarPropertyMgr.getIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        boolean ret = value == STS_FULL_CLOSE || value == STS_HALF_CLOSE || value == STS_STOP_MIN_POSITION;
        Assert.assertTrue(ret);
    }

    @Test
    public void test003_SetDoorMoveStop() {
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, REQ_STOP);
        delay();
        int value = mCarPropertyMgr.getIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        boolean ret = value == STS_STOP_DURING_OPEN || value == STS_STOP_DURING_CLOSE;
        Assert.assertTrue(ret);
    }

    @Test
    public void test004_SetDoorMoveInvaildParam() {
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, 3);
        delay();
        int value = mCarPropertyMgr.getIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        boolean ret = value == STS_STOP_DURING_OPEN || value == STS_STOP_DURING_CLOSE;
        Assert.assertTrue(ret);
    }

    @Test
    public void test005_SetDoorMoveCbk() {
        isFirstCbk = true;
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, REQ_OPEN);
        delay(500);
        propertyCbk = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                if (carPropertyValue.getPropertyId() == VehiclePropertyIds.DOOR_MOVE && carPropertyValue.getAreaId() == VehicleAreaDoor.DOOR_REAR) {
                    if (isFirstCbk) {
                        isFirstCbk = false;
                    } else {
                        int value = (int) carPropertyValue.getValue();
                        boolean ret = value == STS_FULL_CLOSE || value == STS_HALF_CLOSE || value == STS_STOP_MIN_POSITION;
                        Assert.assertTrue(ret);
                        mCarPropertyMgr.unregisterCallback(propertyCbk);
                        cbkTimer.finish();
                    }
                }
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };
        mCarPropertyMgr.registerCallback(propertyCbk, VehiclePropertyIds.DOOR_MOVE, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        mCarPropertyMgr.setIntProperty(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR, REQ_CLOSE);
        cbkTimer.start();
    }

    @Test
    public void test006_SetDoorMoveUnAvail() {
        setAvailable(false);
        delay();
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(VehiclePropertyIds.DOOR_MOVE, VehicleAreaDoor.DOOR_REAR);
        Assert.assertFalse(isAvail);
    }

    private static void setAvailable(boolean isAvail) {
        boolean isFirstSet = false;
        if (ipcpClient == null) {
            ipcpClient = new IpcpClient();
            isFirstSet = true;
        }
        int cemSvcId = 37;
        int cemOperId = 999;
        int[] cemOperIds = {999};
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] ccOperIds = {200};
        int[] configs = {98};
        int[] values = {2};
        if (isFirstSet) {
            ipcpClient.setConfig(cemSvcId, cemOperIds);
            ipcpClient.setConfig(ccSvcId, ccOperIds);
        }
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts", "trOpenerSts"};
        int[] cemValues = {isAvail ? VehicleConstants.CAR_MODE_NOMAL : VehicleConstants.CAR_MODE_TRANSPORT, VehicleConstants.USG_MODE_CONVENIENCE, 2};
        boolean cemRet = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemRet);
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccRet);
    }

}
